
package com.scs.application.modules.settlement.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.model.CommonResult;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.settlement.consts.DictConsts;
import com.scs.application.modules.settlement.entity.Bill;
import com.scs.application.modules.settlement.entity.BillItem;
import com.scs.application.modules.settlement.entity.Invoice;
import com.scs.application.modules.settlement.mapper.BillItemMapper;
import com.scs.application.modules.settlement.mapper.BillMapper;
import com.scs.application.modules.settlement.mapper.InvoiceMapper;
import com.scs.application.modules.settlement.request.BillItemQueryRequest;
import com.scs.application.modules.settlement.service.BillItemService;
import com.scs.application.modules.settlement.vo.BillItemVO;
import com.scs.application.modules.settlement.vo.InvoiceVO;
import com.scs.application.modules.thirdparty.dto.ModelInvoiceSyncDTO;
import com.scs.application.modules.thirdparty.request.InvoiceRequest;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* 记账单明细 service 实现
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class BillItemServiceImpl extends BaseServiceImpl<BillItemMapper, BillItem> implements BillItemService {

    @Autowired
    private BillMapper billMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Override
    public List<BillItem> list(BillItemQueryRequest request) {
        List<BillItem> list = this.list(Wrappers.<BillItem>query()
                .eq(StringUtils.isNotBlank(request.getBillId()), "bill_id", request.getBillId())
            .orderByDesc("gmt_modified")
        );
        return list;
    }

    @Override
    public List<BillItemVO> listForInvoice(BillItemQueryRequest request) {
        return this.baseMapper.listForInvoice(request);
    }

    @Override
    public List<BillItemVO> listBillItems(BillItemQueryRequest request) {
        return this.baseMapper.listBillItems(request);
    }

    @Override
    public IPage<BillItemVO> page(BillItemQueryRequest request) {
        request.setSupplierId(UserUtils.getSupplierId());
        return this.baseMapper.page(request.getPage(), request);
    }

    @Override
    public IPage<BillItemVO> pageForInvoice(BillItemQueryRequest request) {
        request.setSupplierId(UserUtils.getSupplierId());
        return this.baseMapper.pageForInvoice(request.getPage(), request);
    }

    @Override
    public void add(BillItem entity) {
        entity.setStatus(DictConsts.BILL_ITEM_STATUS_UNINVOICE);
        saveOrUpdate(entity);

        //修改记账金额
        Double totalAmount = totalAmount(entity.getBillId());
        Bill bill = new Bill();
        bill.setTotalAmount(totalAmount).setId(entity.getBillId());
        billMapper.updateById(bill);
    }

    @Override
    public void delete(String id) {
        BillItem byId = getById(id);
        if (byId == null){
            throw new BusinessException("数据异常");
        }
        removeCascadeById(id);

        //修改记账金额
        Double totalAmount = totalAmount(byId.getBillId());
        Bill bill = new Bill();
        bill.setTotalAmount(totalAmount).setId(byId.getBillId());
        billMapper.updateById(bill);
    }

    @Override
    public void batchSave(List<BillItem> children) {

        for (BillItem child : children) {
            child.setStatus(DictConsts.BILL_ITEM_STATUS_UNINVOICE);
        }
        saveOrUpdateBatch(children);

        //修改记账金额
        Double totalAmount = totalAmount(children.get(0).getBillId());
        Bill bill = new Bill();
        bill.setTotalAmount(totalAmount).setId(children.get(0).getBillId());
        billMapper.updateById(bill);
    }

    @Override
    public Double totalAmount(String billId) {
        Double totalAmount = baseMapper.totalAmount(billId);
        return totalAmount == null ? 0 : totalAmount;
    }

    @Override
    public CommonResult syncInvoiceStatus(List<ModelInvoiceSyncDTO> modelInvoiceSyncDTOS) {
        if(modelInvoiceSyncDTOS != null && modelInvoiceSyncDTOS.size() > 0) {
            List<String> ids = modelInvoiceSyncDTOS.stream().map(ModelInvoiceSyncDTO::getId).collect(Collectors.toList());
            Collection<Invoice> invoices = invoiceMapper.selectBatchIds(ids);

            if (invoices != null && invoices.size() > 0) {
                invoices.forEach(invoice -> {
                    Invoice invoice1 = new Invoice();
                    Optional<ModelInvoiceSyncDTO> optionalModelInvoiceSyncDTO = modelInvoiceSyncDTOS.stream().filter(modelInvoiceSyncDTO -> modelInvoiceSyncDTO.getId().equals(invoice.getId())).findFirst();
                    if (optionalModelInvoiceSyncDTO.isPresent()) {
                        invoice1.setSyncStatus(Integer.parseInt(optionalModelInvoiceSyncDTO.get().getSyncStatus()))
                                .setId(invoice.getId());
                        invoiceMapper.updateById(invoice1);
                    }
                });
            }
        }
        return CommonResult.ok("同步成功");
    }

    /**
     * 获取发票信息
     * @param invoiceRequest
     * @return
     */
    @Override
    public CommonResult getInvoices(InvoiceRequest invoiceRequest) {
        List<Invoice> invoices = invoiceMapper.selectList(Wrappers.<Invoice>query().eq("hospital_id", UserUtils.getHospitalId())
                .eq("status", DictConsts.INVOICE_STATUS_AUDITED) //0：制单，1：已审核
                .eq("sync_status", DictConsts.INVOICE_SYNC_STATUS_NO) //未同步的
                .eq(StringUtils.isNotBlank(invoiceRequest.getSupplierId()), "supplier_id", invoiceRequest.getSupplierId())
                .gt(invoiceRequest.getBeginDate() != null, "gmt_modified", invoiceRequest.getBeginDate()));

        if(invoices.size() == 0) {
            return CommonResult.ok("获取成功");
        }

        log.info("获取开票单长度：" + invoices.size());

        List<InvoiceVO> invoiceVOS = Lists.newArrayListWithCapacity(invoices.size());

        List<BillItem> billItems = this.list(Wrappers.<BillItem>query().in("invoice_id", invoices.stream().map(invoice -> invoice.getId()).distinct()
                .collect(Collectors.toList())));

        log.info("获取记账单明细长度：" + invoices.size());

        List<Bill> bills = billMapper.selectList(Wrappers.<Bill>query().in("id", billItems.stream().map(billItem -> billItem.getBillId()).distinct()
                .collect(Collectors.toList())));

        log.info("获取记账单长度：" + invoices.size());

        invoices.forEach(invoice -> {
            InvoiceVO invoiceVO = new InvoiceVO();
            BeanUtils.copyProperties(invoice,invoiceVO);
            invoiceVO.setItems(billItems.stream().filter(billItem -> billItem.getInvoiceId().equals(invoice.getId()))
                    .map(billItem -> {
                        BillItemVO billItemVO = new BillItemVO();
                        BeanUtils.copyProperties(billItem, billItemVO);
                        Bill bill = bills.stream().filter(bl -> bl.getId().equals(billItemVO.getBillId())).findAny().orElse(null);
                        if (bill != null) {
                            billItemVO.setDeptName(bill.getDeptName());
                            billItemVO.setDeptCode(bill.getDeptCode());
                        }
                        return billItemVO;
                    } ).collect(Collectors.toList()));
            invoiceVOS.add(invoiceVO);
        });

        return CommonResult.ok("获取成功", invoiceVOS);
    }
}
